home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / tcisam.zip / IWRITE.C < prev   
Text File  |  1987-08-21  |  5KB  |  131 lines

  1. /*
  2.  * IWRITE.C - write record.
  3.  *
  4.  *                      Copyright (c) 1987, Jim Mischel
  5.  * Modifications:
  6.  *
  7.  * 08/13/87 - jim - original coding
  8.  * 08/21/87 - jim - copy source to data buffer before writing
  9.  */
  10.  
  11. #include "inxdefs.h"
  12.  
  13. /*
  14.  * iwrite() - add the data from '*source' to the data file.  Returns 0 if
  15.  * successful, status on error.  If duplicate keys are not permitted and
  16.  * adding the record would casue a duplicate key, the global variable 'ierrno'
  17.  * will be set to I_INVKEY.
  18.  */
  19. int iwrite(void *d, void *src)
  20. {
  21.   df_rec *db_control = (df_rec *)d;
  22.   char *source = (char *)src;
  23.  
  24.   inx_rec irec;                         /* new index record */
  25.   inx_rec save_inx_rec;
  26.   long save_inx_ptr,
  27.        write_pos;
  28.  
  29.   irec.if_flags = 0;
  30.  
  31.   switch (isearch(db_control,(source+db_control->df_key_offset))) {
  32.     case 0      :
  33.         if (!(db_control->df_flags & DF_DUP))   /* check duplicates */
  34.           return(ierror(I_INVKEY));     /* error: duplicate key */
  35.       /*
  36.        * duplicate record key.
  37.        * if the right node is a thread pointer, add the new record at right
  38.        */
  39.         if (db_control->df_inx_buff.if_flags & RTHRD)
  40.           goto set_right;
  41.       /*
  42.        * otherwise get the inorder successor and add the new record as the
  43.        * left son.
  44.        */
  45.         if (iget_next(db_control,&db_control->df_inx_buff)) {
  46.           return(ierrno);
  47.         }
  48.     case -1     :                       /* insert key at left node */
  49.         /* left node of new node is parent's left node */
  50.         irec.if_left_node = db_control->df_inx_buff.if_left_node;
  51.  
  52.         /* right node of new node is parent */
  53.         irec.if_right_node = db_control->df_inx_ptr;
  54.  
  55.         /* both right and left pointers of new node are thread pointers */
  56.         irec.if_flags = (db_control->df_inx_buff.if_flags & BTHRD) +
  57.                         RTHRD + LTHRD;
  58.  
  59.         /* if parent is the header node, this node is end of thread */
  60.         if (db_control->df_inx_ptr == 0L)
  61.           irec.if_flags |= ETHRD;
  62.  
  63.         /* parent's left node points to new node */
  64.         db_control->df_inx_buff.if_left_node = fsize(db_control->df_inx_file);
  65.  
  66.         /* parents left node is NOT a thread pointer */
  67.         db_control->df_inx_buff.if_flags &= (ETHRD+RTHRD);
  68.         break;
  69.     case 1      :                       /* insert key at right node */
  70. set_right:
  71.         /* right node of new node is parent's right node */
  72.         irec.if_right_node = db_control->df_inx_buff.if_right_node;
  73.  
  74.         /* left node of new node is parent */
  75.         irec.if_left_node = db_control->df_inx_ptr;
  76.  
  77.         /* both right and left pointers of new node are thread pointers */
  78.         irec.if_flags = (db_control->df_inx_buff.if_flags & ETHRD) +
  79.                          RTHRD + LTHRD;
  80.  
  81.         /* parent's right node points to new node */
  82.         db_control->df_inx_buff.if_right_node = fsize(db_control->df_inx_file);
  83.  
  84.         /* parent's right node is NOT a thread pointer */
  85.         db_control->df_inx_buff.if_flags &= (LTHRD+BTHRD);
  86.         break;
  87.     default     : return(ierrno);       /* read error */
  88.   } /* switch */
  89.  
  90.   /* data record will go to end of data file */
  91.   irec.if_dat_ptr = fsize(db_control->df_dat_file);
  92.  
  93.   /* new record's parent is current node */
  94.   irec.if_parent = db_control->df_inx_ptr;      
  95.  
  96.   /* save current index record */
  97.   memcpy(&save_inx_rec,&db_control->df_inx_buff,sizeof(inx_rec));
  98.   save_inx_ptr = db_control->df_inx_ptr;        /* save current index pointer */
  99.   write_pos = fsize(db_control->df_inx_file);   /* save new index location */
  100.  
  101.   /*
  102.    * Now we update the index and data files.  This is done as non-destructively
  103.    * as possible.  The new index node is added to the index file first.  Then
  104.    * the new data record is added to the end of the data file.  The last
  105.    * operation performed is to update the old index record.  This ensures
  106.    * the integrity of the binary tree structure.  If an error occurs while
  107.    * writing any of the records, the binary tree remains as it was before
  108.    * adding the new node was attempted.
  109.    */
  110.  
  111.   /* add new index node */
  112.   if (iwrite_inx(db_control,&irec,write_pos))
  113.     return(ierrno);
  114.  
  115.   /* add new data record to end of data file */
  116.   memcpy(db_control->df_dat_buff,source,db_control->df_rec_size);
  117.   if (iwrite_dat(db_control,source,fsize(db_control->df_dat_file)))
  118.     return(ierrno);
  119.  
  120.   /* update the old index record */
  121.   if (iwrite_inx(db_control,&save_inx_rec,save_inx_ptr))
  122.     return(ierrno);
  123.  
  124.   /* make index file point to new record */
  125.   if (iread_inx(db_control,write_pos))
  126.     return(ierrno);
  127.  
  128.   db_control->df_flags &= ~DF_DELETE;           /* clear deleted record flag */
  129.   return(ierror(0));
  130. } /* iwrite */
  131.